package com.renfei.cameralibrary.fragment;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.SurfaceTexture;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;

import com.cgfay.uitls.bean.MusicData;
import com.cgfay.uitls.fragment.MusicPickerFragment;
import com.cgfay.uitls.fragment.PermissionErrorDialogFragment;
import com.cgfay.uitls.utils.BrightnessUtils;
import com.cgfay.uitls.utils.PermissionUtils;
import com.cgfay.uitls.widget.RoundOutlineProvider;
import com.cgfay.widget.CameraTabView;
import com.renfei.cameralibrary.R;
import com.renfei.cameralibrary.camera.CameraParam;
import com.renfei.cameralibrary.model.GalleryType;
import com.renfei.cameralibrary.presenter.CameraPreviewPresenter;
import com.renfei.cameralibrary.widget.CainTextureView;
import com.renfei.cameralibrary.widget.CameraMeasureFrameLayout;
import com.renfei.cameralibrary.widget.CameraPreviewTopbar;
import com.renfei.cameralibrary.widget.CircleProgressBar;
import com.renfei.cameralibrary.widget.PreviewMeasureListener;
import com.renfei.cameralibrary.widget.RecordButton;
import com.renfei.cameralibrary.widget.RecordCountDownView;
import com.renfei.cameralibrary.widget.RecordProgressView;

/**
 * camera预览界面
 */
public class CameraPreviewFragment extends Fragment implements View.OnClickListener,
        CainTextureView.OnMultiClickListener {
    private static final String TAG = "CameraPreviewFragment";
    private static final boolean VERBOSE = true;

    private static final String FRAGMENT_TAG = "FRAGMENT_TAG";
    private static final String FRAGMENT_DIALOG = "dialog";

    /**
     * Fragment主页面
     */
    private View mContentView;
    // 预览部分
    private CameraMeasureFrameLayout mPreviewLayout;
    private CainTextureView mCameraTextureView;
    /**
     * 顶部topbar
     */
    private CameraPreviewTopbar mPreviewTopbar;

    // 录制按钮
    private CircleProgressBar btnRecord;


    private boolean mFragmentAnimating;
    private FrameLayout mFragmentContainer;

    // 滤镜页面
    private PreviewEffectFragment mEffectFragment;
    // 更多设置界面
    private PreviewSettingFragment mSettingFragment;

    private final Handler mMainHandler;
    private Activity mActivity;


    // 预览参数
    private CameraParam mCameraParam;
    //相机预览
    private CameraPreviewPresenter mPreviewPresenter;

    public CameraPreviewFragment() {
        mCameraParam = CameraParam.getInstance();
        mMainHandler = new Handler(Looper.getMainLooper());
        mPreviewPresenter = new CameraPreviewPresenter(this);
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        if (context instanceof Activity) {
            mActivity = (Activity) context;
        } else {
            mActivity = getActivity();
        }
        mPreviewPresenter.onAttach(mActivity);
        Log.d(TAG, "onAttach: ");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPreviewPresenter.onCreate();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mContentView = inflater.inflate(R.layout.fragment_camera_preview, container, false);
        return mContentView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (isCameraEnable()) {
            initView(mContentView);
        } else {
            PermissionUtils.requestCameraPermission(this);
        }

    }

    private void initView(View view) {
        initPreviewSurface();
        initPreviewTopbar();
        initBottomLayout(view);
        //设置录制时长
        mPreviewPresenter.setRecordSeconds(15);
    }


    private void initPreviewSurface() {

        mPreviewLayout = mContentView.findViewById(R.id.layout_camera_preview);
        mCameraTextureView = new CainTextureView(mActivity);
        mCameraTextureView.addMultiClickListener(this);
        mCameraTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {

            @Override
            public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
                Log.d(TAG, "onSurfaceTextureAvailable: ");
                mPreviewPresenter.onSurfaceCreated(surface);
                mPreviewPresenter.onSurfaceChanged(width, height);
            }

            @Override
            public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
                Log.d(TAG, "onSurfaceTextureSizeChanged: ");
                mPreviewPresenter.onSurfaceChanged(width, height);
            }

            @Override
            public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
                Log.d(TAG, "onSurfaceTextureDestroyed: ");
                mPreviewPresenter.onSurfaceDestroyed();

                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
//                Log.d(TAG, "onSurfaceTextureUpdated: ");
            }
        });
        mPreviewLayout.addView(mCameraTextureView);

        // 添加圆角显示
        if (Build.VERSION.SDK_INT >= 21) {
            mCameraTextureView.setOutlineProvider(new RoundOutlineProvider(getResources().getDimension(R.dimen.dp7)));
            mCameraTextureView.setClipToOutline(true);
        }

        mPreviewLayout.setOnMeasureListener(new PreviewMeasureListener(mPreviewLayout));
    }


    private void initPreviewTopbar() {
        mPreviewTopbar = mContentView.findViewById(R.id.camera_preview_topbar);

        mPreviewTopbar.addOnCameraCloseListener(new CameraPreviewTopbar.OnCameraCloseListener() {
            @Override
            public void onCameraClose() {

            }
        });

        mPreviewTopbar.addOnCameraCloseListener(this::closeCamera)
                .addOnCameraSwitchListener(this::switchCamera)
                .addOnShowPanelListener(type -> {
                    switch (type) {
                        case CameraPreviewTopbar.PanelMusic: {
                            openMusicPicker();
                            break;
                        }

                        case CameraPreviewTopbar.PanelSpeedBar: {
//                            setShowingSpeedBar(mSpeedBar.getVisibility() != View.VISIBLE);
                            break;
                        }

                        case CameraPreviewTopbar.PanelFilter: {
                            showEffectFragment();
                            break;
                        }

                        case CameraPreviewTopbar.PanelSetting: {
                            showSettingFragment();
                            break;
                        }
                    }
                });
    }

    /**
     * 初始化底部布局
     *
     * @param view
     */
    private void initBottomLayout(@NonNull View view) {
        mFragmentContainer = view.findViewById(R.id.fragment_bottom_container);

        btnRecord = view.findViewById(R.id.btn_record);
        btnRecord.setRecordEnable(true);
        btnRecord.setRecordButtonListener(new CircleProgressBar.RecordButtonListener() {
            @Override
            public void onRecordStart() {
                Log.e(TAG, "onRecordStart: ");
                mPreviewPresenter.startRecord();
            }

            @Override
            public void onRecordCancel() {
                Log.e(TAG, "onRecordCancel: ");
                mPreviewPresenter.cancelRecord();
            }

            @Override
            public void onRecordFinish() {
                Log.e(TAG, "onRecordStop: ");
                mPreviewPresenter.stopRecord();
            }
        });
    }


    @Override
    public void onStart() {
        super.onStart();
        mPreviewPresenter.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
        //增强光照
        enhancementBrightness();
        mPreviewPresenter.onResume();
        Log.d(TAG, "onResume: ");
    }

    @Override
    public void onPause() {
        super.onPause();
        mPreviewPresenter.onPause();
        Log.d(TAG, "onPause: ");
    }

    @Override
    public void onStop() {
        super.onStop();
        mPreviewPresenter.onStop();
        Log.d(TAG, "onStop: ");
    }

    @Override
    public void onDestroyView() {
        mContentView = null;
        super.onDestroyView();
        Log.d(TAG, "onDestroyView: ");
    }

    @Override
    public void onDestroy() {
        mPreviewPresenter.onDestroy();
        mMainHandler.removeCallbacksAndMessages(null);
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }

    @Override
    public void onDetach() {
        mPreviewPresenter.onDetach();
        mPreviewPresenter = null;
        mActivity = null;
        super.onDetach();
        Log.d(TAG, "onDetach: ");
    }


    @Override
    public void onClick(View v) {
        // int id = v.getId();
        // if (id == R.id.btn_record) {
        //     takePicture();
        // }
    }


    /**
     * 关闭相机
     */
    private void closeCamera() {
        if (mActivity != null) {
            mActivity.finish();
            mActivity.overridePendingTransition(0, R.anim.anim_slide_down);
        }
    }

    /**
     * 切换相机
     */
    private void switchCamera() {
        if (!isCameraEnable()) {
            PermissionUtils.requestCameraPermission(this);
            return;
        }
        mPreviewPresenter.switchCamera();
    }

    /**
     * 显示滤镜页面
     */
    private void showEffectFragment() {
        if (mFragmentAnimating) {
            return;
        }
        if (mEffectFragment == null) {
            mEffectFragment = new PreviewEffectFragment();
        }
        mEffectFragment.addOnCompareEffectListener(compare -> {
            mPreviewPresenter.showCompare(compare);
        });
        mEffectFragment.addOnFilterChangeListener(color -> {
            mPreviewPresenter.changeDynamicFilter(color);
        });
        mEffectFragment.scrollToCurrentFilter(mPreviewPresenter.getFilterIndex());
        if (!mEffectFragment.isAdded()) {
            getChildFragmentManager()
                    .beginTransaction()
                    .add(R.id.fragment_bottom_container, mEffectFragment, FRAGMENT_TAG)
                    .commitAllowingStateLoss();
        } else {
            getChildFragmentManager()
                    .beginTransaction()
                    .show(mEffectFragment)
                    .commitAllowingStateLoss();
        }
        showFragmentAnimating();
    }

    /**
     * 显示设置页面
     */
    private void showSettingFragment() {
        if (mFragmentAnimating) {
            return;
        }
        if (mSettingFragment == null) {
            mSettingFragment = new PreviewSettingFragment();
        }
        mSettingFragment.addStateChangedListener(mStateChangedListener);
        mSettingFragment.setEnableChangeFlash(mCameraParam.supportFlash);
        if (!mSettingFragment.isAdded()) {
            getChildFragmentManager()
                    .beginTransaction()
                    .add(R.id.fragment_bottom_container, mSettingFragment, FRAGMENT_TAG)
//                    .addToBackStack(FRAGMENT_TAG)
                    .commitAllowingStateLoss();
        } else {
            getChildFragmentManager()
                    .beginTransaction()
                    .show(mSettingFragment)
                    .commitAllowingStateLoss();
        }
        showFragmentAnimating();
    }


    /**
     * 增强光照
     */
    private void enhancementBrightness() {
        BrightnessUtils.setWindowBrightness(mActivity, mCameraParam.luminousEnhancement
                ? BrightnessUtils.MAX_BRIGHTNESS : mCameraParam.brightness);
    }


    // ----------------------------------- 顶部状态栏点击回调 ------------------------------------
    private PreviewSettingFragment.StateChangedListener mStateChangedListener = new PreviewSettingFragment.StateChangedListener() {

        @Override
        public void flashStateChanged(boolean flashOn) {

        }

        @Override
        public void onOpenCameraSetting() {
//            mPreviewPresenter.onOpenCameraSettingPage();
        }

        @Override
        public void delayTakenChanged(boolean enable) {
            mCameraParam.takeDelay = enable;
        }

        @Override
        public void luminousCompensationChanged(boolean enable) {
            mCameraParam.luminousEnhancement = enable;
            enhancementBrightness();
        }

        @Override
        public void touchTakenChanged(boolean touchTake) {
            Log.e(TAG, "touchTakenChanged: " + String.valueOf(touchTake));
            mCameraParam.touchTake = touchTake;
        }

        @Override
        public void changeEdgeBlur(boolean enable) {
//            mPreviewPresenter.enableEdgeBlurFilter(enable);
        }

        @Override
        public void videoRecordTimeLenChange(GalleryType galleryType) {
            switch (galleryType) {
                case PICTURE:
                    mCameraParam.mGalleryType = GalleryType.PICTURE;
                    if (!isStorageEnable()) {
                        PermissionUtils.requestRecordSoundPermission(CameraPreviewFragment.this);
                    }
                    if (btnRecord != null) {
                        btnRecord.setRecordEnable(false);
                    }
                    break;
                case VIDEO_60S:
                    mCameraParam.mGalleryType = GalleryType.VIDEO_60S;
                    // 请求录音权限
                    if (!isRecordAudioEnable()) {
                        PermissionUtils.requestRecordSoundPermission(CameraPreviewFragment.this);
                    }
                    if (btnRecord != null) {
                        btnRecord.setRecordEnable(true);
                    }
                    mPreviewPresenter.setRecordSeconds(60);
                    break;
                case VIDEO_15S:
                    mCameraParam.mGalleryType = GalleryType.VIDEO_15S;
                    // 请求录音权限
                    if (!isRecordAudioEnable()) {
                        PermissionUtils.requestRecordSoundPermission(CameraPreviewFragment.this);
                    }
                    if (btnRecord != null) {
                        btnRecord.setRecordEnable(true);
                    }
                    mPreviewPresenter.setRecordSeconds(15);
                    break;
            }

        }
    };

    // -------------------------------------- 权限逻辑处理 ---------------------------------
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PermissionUtils.REQUEST_CAMERA_PERMISSION) {
            if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                PermissionErrorDialogFragment.newInstance(getString(R.string.request_camera_permission), PermissionUtils.REQUEST_CAMERA_PERMISSION, true)
                        .show(getChildFragmentManager(), FRAGMENT_DIALOG);
            } else {
                initView(mContentView);
            }
        } else if (requestCode == PermissionUtils.REQUEST_STORAGE_PERMISSION) {
            if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                PermissionErrorDialogFragment.newInstance(getString(R.string.request_storage_permission), PermissionUtils.REQUEST_STORAGE_PERMISSION)
                        .show(getChildFragmentManager(), FRAGMENT_DIALOG);
            }
        } else if (requestCode == PermissionUtils.REQUEST_SOUND_PERMISSION) {
            if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                PermissionErrorDialogFragment.newInstance(getString(R.string.request_sound_permission), PermissionUtils.REQUEST_SOUND_PERMISSION)
                        .show(getChildFragmentManager(), FRAGMENT_DIALOG);
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * 是否允许拍摄
     *
     * @return
     */
    private boolean isCameraEnable() {
        return PermissionUtils.permissionChecking(mActivity, Manifest.permission.CAMERA);
    }

    /**
     * 判断是否可以录制
     *
     * @return
     */
    private boolean isRecordAudioEnable() {
        return PermissionUtils.permissionChecking(mActivity, Manifest.permission.RECORD_AUDIO);
    }


    /**
     * 判断是否可以读取本地媒体
     *
     * @return
     */
    private boolean isStorageEnable() {
        return PermissionUtils.permissionChecking(mActivity, Manifest.permission.READ_EXTERNAL_STORAGE);
    }

    /**
     * 处理返回按钮事件
     *
     * @return 是否拦截返回按键事件
     */
    public boolean onBackPressed() {
        Fragment fragment = getChildFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        if (fragment != null) {
            hideFragmentAnimating();
            return true;
        }
        return false;
    }


    //******************************** CainTextureView 点击回调监听************************************
    @Override
    public void onSurfaceSingleClick(float x, float y) {
        //单击
    }

    @Override
    public void onSurfaceDoubleClick(float x, float y) {
        Log.e(TAG, "onSurfaceDoubleClick: ");
        //双击
        // 处理浮窗Fragment
        if (onBackPressed()) {
            return;
        }
        if (mCameraParam.touchTake) {
            takePicture();
            return;
        }
    }


    /**
     * 拍照
     */
    private void takePicture() {
        Log.e(TAG, "takePicture: ");
        if (isStorageEnable()) {
            if (mCameraParam.mGalleryType == GalleryType.PICTURE) {
                if (!mCameraParam.takeDelay) {
                    mPreviewPresenter.takePicture();
                }
            }
        } else {
            PermissionUtils.requestStoragePermission(this);
        }
    }

    //**********************视频录制*************************************************************

    /**
     * 取消录制
     */
    public void cancelRecordIfNeeded() {
        // 停止录制
        if (mPreviewPresenter.isRecording()) {
            // 取消录制
            mPreviewPresenter.cancelRecord();
        }
    }

    //**********************录制监听回调*************************************************************
    /**
     * 录制监听器回调
     */
    private RecordButton.RecordStateListener mRecordStateListener = new RecordButton.RecordStateListener() {
        @Override
        public void onRecordStart() {
            mPreviewPresenter.startRecord();
        }

        @Override
        public void onRecordStop() {
            mPreviewPresenter.stopRecord();
        }

        @Override
        public void onZoom(float percent) {

        }
    };


    //**********************fragment 添加，移除 ，以及动画

    /**
     * 显示Fragment动画
     */
    private void showFragmentAnimating() {
        showFragmentAnimating(true);
    }

    /**
     * 显示Fragment动画
     */
    private void showFragmentAnimating(boolean hideAllLayout) {
        if (mFragmentAnimating) {
            return;
        }
        mFragmentAnimating = true;
        mFragmentContainer.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.preview_slide_up);
        mFragmentContainer.startAnimation(animation);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                mFragmentAnimating = false;
                if (hideAllLayout) {
                    hideAllLayout();
                } else {
                    hideWithoutSwitch();
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * 隐藏Fragment动画
     */
    private void hideFragmentAnimating() {
        Log.e(TAG, "hideFragmentAnimating: ");
        if (mFragmentAnimating) {
            return;
        }
        mFragmentAnimating = true;
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.preivew_slide_down);
        mFragmentContainer.startAnimation(animation);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                Log.e(TAG, "onAnimationStart: ");
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Log.e(TAG, "onAnimationEnd: ");
                resetAllLayout();
                removeFragment();
                mFragmentAnimating = false;
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                Log.e(TAG, "onAnimationRepeat: ");
            }
        });
    }

    /**
     * 移除Fragment
     */
    private void removeFragment() {
        Log.e(TAG, "removeFragment: ");
        Fragment fragment = getChildFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        if (fragment != null) {
            Log.e(TAG, "removeFragment: fragment is not null");
            getChildFragmentManager()
                    .beginTransaction()
                    .remove(fragment)
                    .commitAllowingStateLoss();
        } else {
            Log.e(TAG, "removeFragment: fragment is null");
        }
    }


    /**
     * 隐藏所有布局
     */
    private void hideAllLayout() {
        mMainHandler.post(() -> {
            if (mPreviewTopbar != null) {
                mPreviewTopbar.hideAllView();
            }
            if (btnRecord != null) {
                btnRecord.setVisibility(View.GONE);
            }
        });
    }

    /**
     * 隐藏除切换相机按钮外的所有控件
     */
    private void hideWithoutSwitch() {
        mMainHandler.post(() -> {
            if (mPreviewTopbar != null) {
                mPreviewTopbar.hideWithoutSwitch();
            }
            if (btnRecord != null) {
                btnRecord.setVisibility(View.GONE);
            }
        });
    }

    /**
     * 录制状态隐藏
     */
    public void hideOnRecording() {
        mMainHandler.post(() -> {
            if (mPreviewTopbar != null) {
                mPreviewTopbar.hideAllView();
            }
        });
    }


    /**
     * 恢复所有布局
     */
    public void resetAllLayout() {
        mMainHandler.post(() -> {
            if (mPreviewTopbar != null) {
                mPreviewTopbar.resetAllView();
            }
            if (btnRecord != null) {
                btnRecord.setVisibility(View.VISIBLE);
            }
        });
    }


    /**
     * 打开音乐选择页面
     */
    public void openMusicPicker() {
        MusicPickerFragment fragment = new MusicPickerFragment();
        fragment.addOnMusicSelectedListener(
                new MusicPickerFragment.OnMusicSelectedListener() {
                    @Override
                    public void onMusicSelectClose() {
                        Fragment currentFragment = getChildFragmentManager().findFragmentByTag(MusicPickerFragment.TAG);
                        if (currentFragment != null) {
                            getChildFragmentManager()
                                    .beginTransaction()
                                    .remove(currentFragment)
                                    .commitNowAllowingStateLoss();
                        }
                    }

                    @Override
                    public void onMusicSelected(MusicData musicData) {
                        resetAllLayout();
                        mPreviewPresenter.setMusicPath(musicData.getPath());
                        mPreviewTopbar.setSelectedMusic(musicData.getName());
                    }
                });
        getChildFragmentManager()
                .beginTransaction()
                .add(fragment, MusicPickerFragment.TAG)
                .commitAllowingStateLoss();
    }

    /**
     * 录制结束 获取到视频文件路径
     * @param mOutputPath
     */
    public void recordFinished(String mOutputPath) {

    }
}
